<script setup lang="ts">
import { ref, onBeforeMount, onMounted, h } from 'vue'
import { message } from 'ant-design-vue'
import useRouteList, { actionKeys } from './routeList'
import { listToTree, setTableHeight, setFixedColumnWidth } from '@/common/utils'
//import searchPanel from '@/components/SearchPanel'
import {layoutRouteName} from "@/router/config"
import tableColSetting from '@/components/tableColsSetting/tableColsSetting.vue'
import Add from './add.vue'
import Update from './update.vue'
import { primaryColor_hex } from '@/theme/config'
import { useResizeLR } from '@/hooks/useResizeLR'

const columns = ref<objType[]>([
	{
		title: '路由名',
		dataIndex: 'name',
		key: 'name',
		width: 120,
		align: 'center',
	},
	{
		title: '组件路径',
		dataIndex: 'component',
		key: 'component',
		width: 150,
		// align:'center',
		ellipsis: true,
	},
	{
		title: '父级路由标题',
		dataIndex: 'pTitle',
		key: 'pTitle',
		width: 100,
		align: 'center',
	},
	{
		title: 'meta',
		dataIndex: 'meta',
		key: 'meta',
		children: [
			{
				title: '页面标题',
				dataIndex: 'title',
				key: 'title',
				width: 150,
				align: 'center',
			},
			{
				title: '菜单图标',
				dataIndex: 'icon',
				key: 'icon',
				width: 150,
				align: 'center',
			},
			{
				title: '一级菜单的排序序号',
				dataIndex: 'rank',
				key: 'rank',
				width: 150,
				align: 'center',
			},
			{
				title: '是否需要权限访问',
				dataIndex: 'noNeedAuth',
				key: 'noNeedAuth',
				width: 150,
				align: 'center',
				// customRender: ({ text: v }: { text: boolean }) => {
				// 	return v ? '否' : '是'
				// },
				customRender: ({ text: v }: { text: boolean }) => {
					return v ? h('span', { style: { color: 'rgb(245, 108, 108)' } }, '否') : h('span', { style: { color: 'rgb(29, 165, 122)' } }, '是')
				},
			},
			{
				title: '是否缓存',
				dataIndex: 'noKeepAlive',
				key: 'noKeepAlive',
				width: 100,
				align: 'center',
				customRender: ({ text: v }: { text: boolean }) => {
					return v ? '否' : '是'
				},
			},
			{
				title: '是否存在菜单中',
				dataIndex: 'onInMenu',
				key: 'noInMenu',
				width: 120,
				align: 'center',
				customRender: ({ text: v }: { text: boolean }) => {
					return v ? '否' : '是'
				},
			},
			{
				title: '是否隐藏菜单',
				dataIndex: 'hiddenMenu',
				key: 'hiddenMenu',
				width: 100,
				align: 'center',
				customRender: ({ text: v }: { text: boolean }) => {
					return v ? '是' : '否'
				},
			},
			{
				title: '是否隐藏布局',
				dataIndex: 'hiddenLayout',
				key: 'hiddenLayout',
				width: 100,
				align: 'center',
				customRender: ({ text: v }: { text: boolean }) => {
					return v ? '是' : '否'
				},
			},
			{
				title: '是否固定tab页',
				dataIndex: 'affix',
				key: 'affix',
				width: 120,
				align: 'center',
				customRender: ({ text: v }: { text: boolean }) => {
					return v ? '是' : '否'
				},
			},
			{
				title: '是否跳往外部链接',
				dataIndex: 'link',
				key: 'link',
				width: 135,
				align: 'center',
				customRender: (scope: any) => {
					return scope.text ? '是' : '否'
				},
			},
		],
	},
	{
		title: '操作',
		key: 'operation',
		fixed: 'right',
		align: 'center',
		// width: 125,  // 如果是动态列宽的话不能给宽度，否则在出现横向滚动条时会有个占位
	},
])
const fixedColWidth = ref<string | number>('0px')
const treeData = ref<routeTreeNode[]>([])
const expandedKeys = ref<string[]>([layoutRouteName])
const selectedKeys = ref<string[]>([])
const hasChildKeys=ref<Set<string>>(new Set([]))
const tableHeight = ref<number>(200)
const treeHeight = ref<number>()
const isSearching = ref(false)
const searchList = ref<routeTreeNode[]>([])
const addModalVisible = ref(false)
const selectedNode = ref({} as routeTreeNode)
const updateModalVisible = ref(false)
const editNode = ref({} as routeTreeNode)
const current = ref(1)
const pageSize = ref(20)
const searchOptions = ref<searchOptionType[]>([
	{ type: 'input', id: 'name', props: { label: '路由名' } },
	{ type: 'input', id: 'component', props: { label: '组件路径' } },
	{ type: 'input', id: 'pTitle', props: { label: '父路由标题' } },
	{ type: 'input', id: 'title', props: { label: '路由标题' } },
	{
		type: 'select',
		id: 'noNeedAuth',
		props: { label: '是否需要权限访问' },
		innerComponentProps: {
			filterable: true,
			options: [
				{ label: '是', value: 0, disabled: false },
				{ label: '否', value: 1, disabled: false },
			],
		},
	},
	{
		type: 'select',
		id: 'onInMenu',
		props: { label: '是否存在在菜单' },
		innerComponentProps: {
			filterable: true,
			options: [
				{ label: '是', value: 0, disabled: false },
				{ label: '否', value: 1, disabled: false },
			],
		},
	},
	{
		type: 'select',
		id: 'noKeepAlive',
		props: { label: '是否缓存' },
		innerComponentProps: {
			filterable: true,
			options: [
				{ label: '是', value: 0, disabled: false },
				{ label: '否', value: 1, disabled: false },
			],
		},
	},
])

const routeList = useRouteList()

useResizeLR({
	containerSelector: '.routeManage .container',
	leftBoxSelector: '.routeManage .container .left',
	moveBarSelector: '.routeManage .container .bar',
	rightBoxSelector: '.routeManage .container .right',
	//  lMinW:180,
	rMinW: 800,
	innerMarginW:10,
})

onBeforeMount(() => {
	getList()
})
// getList()
onMounted(() => {
	fixedColWidth.value = setFixedColumnWidth([actionKeys.update, actionKeys.delete], columns)
})

// 页面内函数统一使用function，箭头函数不能提升，书写顺序上有一定局限性

// 如果页面未使用 search-panel 组件，请在挂载钩子设置表格高度
function handleSearchPanelcollapsed(h: number) {
	setTableHeight({
		tableHeightRef: tableHeight,
		otherSectionHeight: h,
		tHeaderHeight: 77,
	})
	setTableHeight({
		tableHeightRef: treeHeight,
		otherSectionHeight: 52 + h,
		isTable: false,
	})
}

async function getList() {
	const res = await routeList.getList()
	if (res.code) {
		getTreeData(res.list as routeTreeNode[])
	}
}

function getTreeData(list = routeList.list) {
	const tree = listToTree<routeTreeNode>(list, 'id', 'pId', false, (i) => {
		if (i.component || i.link) i.style = { color: primaryColor_hex }
	},(j=>{hasChildKeys.value.add(j.name)})) as routeTreeNode
	// console.log(tree,[...list])
	tree.children?.sort((a, b) => {
		let aRank = a.rank
		let bRank = b.rank
		if (!aRank) aRank = 999
		if (!bRank) bRank = 999
		return aRank - bRank
	})
	treeData.value = [tree]
	// console.log([...hasChildKeys.value])
	// console.log(tree)
}

function handleSearch(value: any) {
	//  console.log(value)
	let list: routeTreeNode[] = JSON.parse(JSON.stringify(routeList.list))
	Object.keys(value).forEach((k) => {
		if (k == 'name') list = list.filter((v) => v.name.includes(value[k]) || value[k].includes(v.name))
		if (k == 'component') list = list.filter((v) => (v.component && v.component.includes(value[k])) || (v.component && value[k].includes(v.component)))
		if (k == 'pTitle') list = list.filter((v) => (v.pTitle && v.pTitle.includes(value[k])) || (v.pTitle && value[k].includes(v.pTitle)))
		if (k == 'title') list = list.filter((v) => v.title.includes(value[k]) || value[k].includes(v.title))
		if (k == 'noNeedAuth') list = list.filter((v) => Boolean(v.noNeedAuth) == Boolean(value[k]))
		if (k == 'onInMenu') list = list.filter((v) => Boolean(v.onInMenu) == Boolean(value[k]))
		if (k == 'noKeepAlive') list = list.filter((v) => Boolean(v.noKeepAlive) == Boolean(value[k]))
	})
	searchList.value = list
	isSearching.value = true
}

function reset() {
	isSearching.value = false
	selectedKeys.value.pop()
	getList()
}

function handleSelectTreeNode(selectedKeys: any, e: any) {
	//  console.log(selectedKeys,e)
	if (selectedKeys[0]) {
		searchList.value = routeList.list.filter((v) => v.name == selectedKeys[0])
		isSearching.value = true
		selectedNode.value = e.node.dataRef
	} else {
		isSearching.value = false
		selectedNode.value = {} as routeTreeNode
	}
	//console.log({...selectedNode.value})
}

function handleAdd() {
	if (!selectedKeys.value.length) {
		message.warn('请先在左侧树选择父节点')
		return
	}
	if (selectedNode.value.component) {
		message.warn('选中的是叶子节点，不可添加子路由')
		return
	}
	if (selectedNode.value.link) {
		message.warning('选中的是外部链接，不可添加子路由')
		return
	}
	addModalVisible.value = true
}

function hanldeAddModalClose(isSuccess: boolean) {
	addModalVisible.value = false
	if (isSuccess) {
		message.success('新增成功')
		getTreeData()
	}
}

async function handleDelete(row: routeTreeNode) {
	const res = await routeList.deleteItem({ id: row.id as number })
	if (res && res.code) {
		message.success('删除成功')
		if (isSearching.value) {
			isSearching.value = false
			selectedKeys.value.pop()
		}
		getTreeData()
	}
}

function handleUpdate(row: routeTreeNode) {
	//console.log(row)
	editNode.value = row
	updateModalVisible.value = true
}
function hanldeUpdateModalClose(isSuccess: boolean) {
	updateModalVisible.value = false
	if (isSuccess) {
		message.success('更新成功')
		getTreeData()
	}
}

function handleColumnsChange(list: objType[]) {
	//console.log(list)
	columns.value = list
}
</script>

<template>
	<div class="routeManage">
		<search-panel @collapsed="handleSearchPanelcollapsed" @search="handleSearch" @reset="reset" :options="searchOptions" />
		<div class="container" style="display: flex">
			<div class="left" :style="{ height: treeHeight + 'px' }">
				<a-tree
					:fieldNames="{ children: 'children', title: 'title', key: 'name' }"
					v-model:expandedKeys="expandedKeys"
					v-model:selectedKeys="selectedKeys"
					:treeData="treeData"
					@select="handleSelectTreeNode"
				/>
			</div>
			<div class="bar" :style="{ height: treeHeight + 'px' }"></div>
			<div class="right">
				<div class="tableTool">
					<a-button type="primary" style="margin-right: 5px" @click="handleAdd" v-if="$hasAuth([actionKeys.add])">新增子路由</a-button>
					<tableColSetting :list="columns" :fixedColWidth="fixedColWidth" @confirm="handleColumnsChange" />
				</div>

				<!-- 'max-content':保证每一列完整显示 -->
				<a-table
					:dataSource="isSearching ? searchList : routeList.list"
					:columns="columns"
					size="small"
					style="width: 100%"
					class="myTable"
					rowKey="name"
					:scroll="{ x: '100%', y: tableHeight }"
					:pagination="{current:current,pageSize,total:routeList.list.length,onChange:(num:number,pageSize:number)=>{current=num}}"
				>
					<template #bodyCell="{ record, column }: any">
						<template v-if="column.key === 'operation'">
							<a-button type="primary" size="small" @click="handleUpdate(record)" style="margin-right: 5px" v-if="$hasAuth([actionKeys.update])" :disabled="record.name==layoutRouteName">修改</a-button>
							<a-popconfirm
								title="确定要删除吗?"
								ok-text="确定"
								cancel-text="取消"
								@confirm="handleDelete(record)"
								placement="topLeft"
								:disabled="[...hasChildKeys].includes(record.name)"
								v-if="$hasAuth([actionKeys.delete])"
							>
								<!-- 后方没按钮就不写外边距，否则按钮的排列会不居中 -->
								<a-button type="danger" size="small" :disabled="[...hasChildKeys].includes(record.name)" style="margin-right: 0px">删除</a-button>
							</a-popconfirm>
						</template>
					</template>
				</a-table>
			</div>
		</div>

		<Add :visible="addModalVisible" :parentNode="(selectedNode as any)" @close="hanldeAddModalClose" />

		<Update :visible="updateModalVisible" :editNode="(editNode as any)" @close="hanldeUpdateModalClose" />
	</div>
</template>

<style scoped lang="less">
.routeManage {
	.container {
		.left {
			overflow: hidden auto;
			margin-top: 52px;
			background-color: white;
			width: 180px;
			flex-shrink: 0;
		}
		.bar {
			width: 5px;
			background-color: gainsboro;
			margin: 52px 0 0 10px;
			background-clip: content-box;
			padding: 0 2px;
			flex-shrink: 0;
		}
		.right {
			padding-left: 20px;
			width: calc(100% - 180px - 15px);
		}
	}

	.tableTool {
		padding: 10px 0;
		display: flex;
		justify-content: flex-end;
		align-items: center;
	}

	:deep(.ant-tree-node-content-wrapper) {
		white-space: nowrap;
	}
}
</style>
